<?php

namespace app\data\controller\api\auth;

use app\data\controller\api\Auth;
use app\data\service\GoodsService;
use app\data\service\OrderService;
use app\data\service\PaymentService;
use app\data\service\UserAdminService;
use think\admin\extend\CodeExtend;
use think\exception\HttpResponseException;

/**
 * 用户牛订单数据接口
 * Class Order
 * @package app\data\controller\api\auth
 */
class CattleOrder extends Auth
{
    /**
     * 控制器初始化
     */
    protected function initialize()
    {
        parent::initialize();
        if (empty($this->user['status'])) {
            $this->error('账户已被冻结，不能操作牛订单数据哦！');
        }
    }

    /**
     * 牛订单状态统计
     */
    public function total()
    {
//        牛订单流程状态(0=已取消;2=待付款;4=待签约;5=持有中;6=已交接)
        $data = ['t0' => 0, 't1' => 0, 't2' => 0, 't3' => 0, 't4' => 0, 't5' => 0, 't6' => 0];
        $query = $this->app->db->name('ShopOrder')->where('module', 1)->where(['uuid' => $this->uuid, 'deleted_status' => 0]);
        foreach ($query->field('status,count(1) count')->group('status')->cursor() as $item) {
            $data["t{$item['status']}"] = $item['count'];
        }
        $this->success('获取牛订单统计', $data);
    }

    /**
     * 获取牛订单列表
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function get()
    {
        $status = input('status');
        if ((!empty($status) || $status == 0) && $status !== '') {
            $map = ['uuid' => $this->uuid, 'deleted_status' => 0, 'status' => $status];
        } else {
            $map = ['uuid' => $this->uuid, 'deleted_status' => 0];
        }

        $query = $this->_query('ShopOrder');
        $result = $query->where($map)->where('module', 1)->order('id desc')->page(true, false, false, 20);
        if (count($result['list']) > 0) OrderService::instance()->buildData($result['list']);
        $this->success('获取牛订单数据成功！', $result);
    }

    /**
     * 牛订单详情
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function detail()
    {
        [$map, $order] = $this->getOrderData();
        $response = [$order];
        OrderService::instance()->buildData($response);
        $this->success('获取牛订单数据成功！', $response[0]);
    }

    /**
     * 用户创建牛订单
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function add()
    {
        $data = $this->_vali([
            'code.require' => '商品编号不能为空',
            'cart_id.default' => 0,
            'order_remark.default' => '',
            'uuid.default' => $this->uuid,
        ]);

        // 检查用户状态
        $this->checkUserStatus();

        // 商品信息检查
        $goodsInfo = $this->app->db->name('ShopGoods')->where(['code' => $data['code'], 'status' => 1, 'deleted' => 0, 'module' => 1])->find();
        if (empty($goodsInfo)) $this->error('牛查询异常');
        $list = [$goodsInfo];
        GoodsService::instance()->bindData($list);
        $goodsInfo = $list[0] ?? [];

        // 商品库存检查
        if ($goodsInfo['stock_total'] < 1) $this->error('牛库存不足');

        try {

            $order['uuid'] = $data['uuid'];
            $order['status'] = 2;
            $order['module'] = 1;
            $order['order_no'] = CodeExtend::uniqidDate(18, 'N');
            // 统计商品数量
            $order['number_goods'] = 1;
            // 统计商品金额
            $order['amount_goods'] = $goodsInfo['price_selling'];
            // 统计牛订单金额
            $order['amount_real'] = $order['amount_goods'];
            $order['amount_total'] = $order['amount_goods'];
            $order['order_remark'] = $data['order_remark'];

            $orderItem = [
                'module' => 1,
                'uuid' => $order['uuid'],
                'order_no' => $order['order_no'],
                'goods_code' => $goodsInfo['code'],
                'goods_spec' => '',
                'goods_name' => $goodsInfo['name'],
                'goods_cover' => $goodsInfo['cover'],
                'price_market' => $goodsInfo['price_market'],
                'price_selling' => $goodsInfo['price_selling'],
                'total_market' => $goodsInfo['price_market'],
                'total_selling' => $goodsInfo['price_selling'],
                'stock_sales' => 1,
                'json' => json_encode($goodsInfo),
            ];

            // 写入商品数据
            $this->app->db->transaction(function () use ($order, $orderItem) {
                $this->app->db->name('ShopOrder')->insert($order);
                $this->app->db->name('ShopOrderItem')->insert($orderItem);
                if (!empty($order['cart_id'])) {
                    $this->app->db->name('ShopGoodsCarts')->where('id', $order['cart_id'])->delete();
                }
                // 同步商品库存销量
                GoodsService::instance()->operateStock($orderItem['goods_code'], '', $orderItem['stock_sales'], 'sale');
            });

            // 触发牛订单创建事件
            $this->app->event->trigger('ShopOrderCreate', $order['order_no']);
            // 返回处理成功数据
            $this->success('下单成功', $order);
        } catch (HttpResponseException $exception) {
            throw $exception;
        } catch (\Exception $exception) {
            $this->error("下单失败，{$exception->getMessage()}");
        }
    }

    /**
     * 获取牛订单支付状态
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function payment()
    {
        $data = $this->_vali([
            'uuid.value'            => $this->uuid,
            'order_no.require'      => '单号不能为空',
            'order_remark.default'  => '',
            'payment_type.require'  => '支付不能为空', // 支付方式(wechat_app=微信;alipay_app=支付宝;yunshanfu=云闪付;large_payment=大额支付)
        ]);
//        $data = $this->_vali([
//            'uuid.value'            => $this->uuid,
//            'order_no.require'      => '单号不能为空',
//            'order_remark.default'  => '',
//            'payment_code.require'  => '支付不能为空',
//            'payment_back.default'  => '', # 支付回跳地址
//            'payment_image.default' => '', # 支付凭证图片
//        ]);
        [$map, $order] = $this->getOrderData();
        if ($order['status'] !== 2) $this->error('不能发起支付');
        if ($order['payment_status'] > 0) $this->error('已经完成支付');
        // 更新牛订单备注
        if (!empty($data['order_remark'])) {
            $this->app->db->name('ShopOrder')->where($map)->update([
                'order_remark' => $data['order_remark'],
            ]);
        }

        // todo
        $this->error('todo', []);
        // 自动处理用户字段
        $openid = '';
        if (in_array($this->type, [UserAdminService::API_TYPE_WXAPP, UserAdminService::API_TYPE_WECHAT])) {
            $openid = $this->user[UserAdminService::TYPES[$this->type]['auth']] ?? '';
            if (empty($openid)) $this->error("发起支付失败");
        }
        try {
            // 返回牛订单数据及支付发起参数
            $type = $order['amount_real'] <= 0 ? 'empty' : $data['payment_code'];
            $param = PaymentService::instance($type)->create($openid, $order['order_no'], $order['amount_real'], '商城牛订单支付', '', $data['payment_back'], $data['payment_image']);
            $this->success('获取支付参数', ['order' => $this->app->db->name('ShopOrder')->where($map)->find() ?: new \stdClass(), 'param' => $param]);
        } catch (HttpResponseException $exception) {
            throw $exception;
        } catch (\Exception $exception) {
            $this->error($exception->getMessage());
        }
    }

    /**
     * 【测试使用】模拟支付
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function mock()
    {
        $map = $this->_vali([
            'order_no.require'      => '单号不能为空',
        ]);
        $order = $this->app->db->name('ShopOrder')->where($map)->find();
        if (in_array($order['status'], [0, 1, 2])) {
            $this->app->db->name('ShopOrder')->where($map)->update([
                'status'          => 4,
                'payment_type'     => 'mock_pay',
                'payment_code'     => 'mock_pay',
                'payment_trade'    => 'mock-' . time(),
                'payment_status'   => 1,
                'payment_datetime' => date('Y-m-d H:i:s'),
            ]);

            $this->success('模拟支付成功');
        } else {
            $this->error('模拟支付失败，该状态不能模拟支付');
        }
    }

    /**
     * 主动取消未支付的牛订单
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function cancel()
    {
        [$map, $order] = $this->getOrderData();
        if (in_array($order['status'], [1, 2, 3])) {
            $result = $this->app->db->name('ShopOrder')->where($map)->update([
                'status'          => 0,
                'cancel_status'   => 1,
                'cancel_remark'   => '用户主动取消牛订单',
                'cancel_datetime' => date('Y-m-d H:i:s'),
            ]);
            if ($result !== false && OrderService::instance()->stock($order['order_no'])) {
                // 触发牛订单取消事件
                $this->app->event->trigger('ShopOrderCancel', $order['order_no']);
                // 返回处理成功数据
                $this->success('牛订单取消成功');
            } else {
                $this->error('牛订单取消失败');
            }
        } else {
            $this->error('牛订单不可取消');
        }
    }

    /**
     * 获取输入牛订单
     * @return array [map, order]
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function getOrderData(): array
    {
        $map = $this->_vali(['uuid.value' => $this->uuid, 'order_no.require' => '单号不能为空']);
        $order = $this->app->db->name('ShopOrder')->where($map)->find();
        if (empty($order)) $this->error('读取牛订单失败');
        return [$map, $order];
    }

    /**
     * 订单交接申请
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function handoverApplication()
    {
        $data = $this->_vali([
            'handover_application_status.require'      => '申请状态不能为空',
        ]);

        [$map, $order] = $this->getOrderData();
        if (!in_array($order['status'], [5])) {
            $this->error('牛订单状态不可申请该操作');
        }
        if (!$order['handover_status']) {
            $this->error('牛订单已交接状态，不可申请该操作');
        }
        if (!$order['handover_application_status']) {
            $this->error('已经在申请中了');
        }

        $result = $this->app->db->name('ShopOrder')->where($map)->update([
            'handover_application_status'  => $data['handover_application_status'],
        ]);

        if ($result !== false) {
            // 返回处理成功数据
            $this->success('操作成功');
        } else {
            $this->error('操作失败');
        }
    }

}